package com.yhk.wuchat.common.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yhk.wuchat.common.common.annotation.RedissonLock;
import com.yhk.wuchat.common.common.domain.enums.YesOrNoEnum;
import com.yhk.wuchat.common.common.service.LockService;
import com.yhk.wuchat.common.common.util.AssertUtil;
import com.yhk.wuchat.common.user.dao.UserBackpackDao;
import com.yhk.wuchat.common.user.domain.entity.UserBackpack;
import com.yhk.wuchat.common.user.domain.enums.IdempotentEnum;
import com.yhk.wuchat.common.user.service.IUserBackpackService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.aop.framework.AopContext;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;

/**
 * @version 1.0
 * @Author moresuo
 * @Date 2024/4/14 15:36
 * @注释
 */
@Service
public class UserBackpackServiceImpl implements IUserBackpackService {

    @Resource
    private LockService lockService;
    @Resource
    private UserBackpackDao userBackpackDao;
    @Resource
    @Lazy
    private UserBackpackServiceImpl userBackpackService;

    /**
     * 给用户发放一个物品
     * @param uid 用户id
     * @param itemId 物品id
     * @param idempotentEnum 幂等类型
     * @param businessId 幂等唯一标识
     */
    public void acquireItem(Long uid, Long itemId, IdempotentEnum idempotentEnum, String businessId) {
        String idempotent = getIdempotent(itemId, idempotentEnum, businessId);
        userBackpackService= (UserBackpackServiceImpl) AopContext.currentProxy();
        userBackpackService.doAcquireItem(uid,itemId,idempotent);
    }

    /**
     * 获取分布式锁，执行具体的业务代码
     * @param uid
     * @param itemId
     * @param idempotent
     */
    @RedissonLock(key = "#idempotent", waitTime = 5000)
    @Transactional
    public void doAcquireItem(Long uid,Long itemId,String idempotent){
        UserBackpack userBackpack = userBackpackDao.getByIdemptent(idempotent);
        if(Objects.nonNull(userBackpack)){
            return;
        }
        UserBackpack insert = UserBackpack.builder()
                .uid(uid)
                .itemId(itemId)
                .status(YesOrNoEnum.NO.getStatus())
                .idempotent(idempotent)
                .build();
        userBackpackDao.save(insert);
    }

    /**
     * 生成幂等号
     * @param itemId
     * @param idempotentEnum
     * @param businessId
     * @return
     */
    private String getIdempotent(Long itemId, IdempotentEnum idempotentEnum, String businessId) {
        return String.format("%d_%d_%s",itemId,idempotentEnum.getType(),businessId);
    }


}
